package com.xhwl.data.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xhwl.common.dto.cent.sdata.AreaDTO;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.query.cent.sdata.AreaQuery;
import com.xhwl.common.utils.StringUtils;
import com.xhwl.data.pojo.vo.NameCheckedVO;
import com.xhwl.data.service.IAreaService;
import com.xhwl.data.service.IOrganizationTypeService;
import com.xhwl.data.service.IRegionService;
import com.xhwl.data.service.ISpaceFunctionTypeService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: luyi
 * @Description: 校区
 * @Date: Create in 15:45 2021/1/22
 */
@RestController
public class AreaController {

    @Autowired
    private IAreaService areaService;

    @Autowired
    private IRegionService regionCentService;

    @Autowired
    private ISpaceFunctionTypeService spaceFunctionTypeService;

    @Autowired
    private IOrganizationTypeService organizationTypeService;

    @RequestMapping(value = "/area/insert", method = RequestMethod.POST)
    public ResultJson insert(@RequestBody AreaDTO area, Account account) {

        if(null != area.getBuildingArea() && area.getBuildingArea().toString().length() > 13){
            return ResultJson.fail("建筑面积参数错误");
        }
        if(null != area.getOccupiedArea() && area.getOccupiedArea().toString().length() > 13){
            return ResultJson.fail("占地面积参数错误");
        }
        if(org.apache.commons.lang3.StringUtils.isEmpty(area.getName()) || area.getName().length() > 50){
            return ResultJson.fail("名称输入错误");
        }
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(area.getCode()) && area.getCode().length() > 36){
            return ResultJson.fail("编码输入错误");
        }
        if(null != area.getProvinceId() && area.getProvinceId().toString().length() > 9){
            return ResultJson.fail("省错误");
        }
        if(null != area.getCityId() && area.getCityId().toString().length() > 9){
            return ResultJson.fail("市错误");
        }
        if(null != area.getDistrictId() && area.getDistrictId().toString().length() > 9){
            return ResultJson.fail("区错误");
        }
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(area.getAddress()) && area.getAddress().length() > 128){
            return ResultJson.fail("地址输入错误");
        }
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(area.getLongitude()) && area.getLongitude().length() > 32){
            return ResultJson.fail("经度错误");
        }
        if(org.apache.commons.lang3.StringUtils.isNotEmpty(area.getLatitude()) && area.getLatitude().length() > 32){
            return ResultJson.fail("纬度错误");
        }
        if(null != area.getOrganizationId() && area.getOrganizationId().toString().length() > 9){
            return ResultJson.fail("组织id错误");
        }
        area.setIndustryId(account.getIndustryId());
        if (null == area.getId()) {
            return areaService.create(area);
        } else {
            return areaService.update(area);
        }
    }

    @RequestMapping(value = "/area/batch-insert", method = RequestMethod.POST)
    public ResultJson batchInsert(@RequestBody List<AreaDTO> areas){

        if(CollectionUtils.isEmpty(areas)){
            return ResultJson.fail("参数错误");
        }
        long count = areas.stream().map(AreaDTO::getCode).distinct().count();
        if(areas.size() > count){
            return ResultJson.fail("编码重复");
        }
        for(AreaDTO areaDTO : areas){
            if(null != areaDTO.getBuildingArea() && areaDTO.getBuildingArea().toString().length() > 13){
                return ResultJson.fail("建筑面积参数错误");
            }
            if(null != areaDTO.getOccupiedArea() && areaDTO.getOccupiedArea().toString().length() > 13){
                return ResultJson.fail("占地面积参数错误");
            }
        }
        return areaService.batchCreate(areas);
    }


    @RequestMapping(value = "/area/page", method = RequestMethod.POST)
    public ResultJson page(@RequestBody AreaQuery areaQuery, Page page) {
        Page<Area> page1 = areaService.page(areaQuery, page);
        return ResultJson.success(convertDTO(page1,areaQuery.getTypeId()));
    }

    @RequestMapping(value = "/area/delete")
    public ResultJson delete(@RequestParam Integer id, Account account) {
        return areaService.delete(id, account);
    }

    @RequestMapping(value = "/area/name-check", method = RequestMethod.POST)
    public ResultJson nameCheck(@RequestBody NameCheckedVO nameChecked){
        AreaQuery areaQuery = new AreaQuery();
        if(null == nameChecked || StringUtils.isEmpty(nameChecked.getName())){
            return ResultJson.fail("检查不通过");
        }
        if(10 < nameChecked.getName().trim().length()){
            return ResultJson.fail("请输入10个以内字符");
        }
        if(null == nameChecked.getParentId()){
            return ResultJson.fail("参数错误");
        }
        if(null != nameChecked.getId()){
            areaQuery.withExcludeId(nameChecked.getId());
        }
        areaQuery.withName(nameChecked.getName());
        areaQuery.withParentId(nameChecked.getParentId());
        List<Area> list = areaService.list(areaQuery);
        if(list.size() > 0){
            return ResultJson.fail("名称重复");
        }
        return ResultJson.success("名称可用");
    }

    @RequestMapping(value = "/area/detail")
    public ResultJson detail(Integer id, Integer orgId, Account account,Integer typeId){
        if(null == id && null == orgId){
            return ResultJson.fail("参数错误");
        }
        AreaQuery areaQuery = new AreaQuery();
        areaQuery.withId(id);
//        areaQuery.withIndustryId(account.getIndustryId());
        areaQuery.withOrgId(orgId);
        Area area = areaService.one(areaQuery, account);
        if(null == area){
            return ResultJson.success();
        }
        List<SpaceFunctionType> spaceFunctionTypes = this.listFunctionType();
        AreaDTO areaDTO = processBean(area, spaceFunctionTypes,typeId);
        return ResultJson.success(areaDTO);
    }

    private void setRegionName(AreaDTO areaDTO){
        List<Integer> regionIds = new ArrayList<>();
        if(null != areaDTO.getProvinceId()){
            regionIds.add(areaDTO.getProvinceId());
        }
        if(null != areaDTO.getCityId()){
            regionIds.add(areaDTO.getCityId());
        }
        if(null != areaDTO.getDistrictId()){
            regionIds.add(areaDTO.getDistrictId());
        }
        if(!regionIds.isEmpty()){
            List<Region> regions = regionCentService.findByIds(regionIds);
            Map<Integer, String> reMap = regions.stream().collect(Collectors.toMap(Region::getId, Region::getName));
            if(StringUtils.isNotEmpty(reMap.get(areaDTO.getProvinceId()))){
                areaDTO.setProvinceName(reMap.get(areaDTO.getProvinceId()));
            }
            if(StringUtils.isNotEmpty(reMap.get(areaDTO.getCityId()))){
                areaDTO.setCityName(reMap.get(areaDTO.getCityId()));
            }
            if(StringUtils.isNotEmpty(reMap.get(areaDTO.getDistrictId()))){
                areaDTO.setDistrictName(reMap.get(areaDTO.getDistrictId()));
            }
        }
    }


    private Page<AreaDTO> convertDTO(Page page,Integer typeId) {
        List<Area> areas = page.getRecords();
        if (null == areas || areas.isEmpty()) {
            return page;
        }
        List<AreaDTO> result = new ArrayList<>(areas.size());
        List<SpaceFunctionType> spaceFunctionTypes = this.listFunctionType();
        for (Area area : areas) {
            AreaDTO areaDTO = processBean(area, spaceFunctionTypes,typeId);
            result.add(areaDTO);
        }
        return page.setRecords(result);
    }

    private AreaDTO processBean(Area area, List<SpaceFunctionType> spaceFunctionTypes,Integer typeId) {
        AreaDTO areaDTO = new AreaDTO();
        BeanUtils.copyProperties(area, areaDTO);
        //填充功能名称
        if (null != area.getFunctionType()) {
            for (SpaceFunctionType spaceFunctionType : spaceFunctionTypes) {
                if (spaceFunctionType.getId().equals(area.getFunctionType())) {
                    areaDTO.setFunctionName(spaceFunctionType.getName());
                    break;
                }
            }
        }
        List<Integer> areaList = new ArrayList<>(3);
        if (null != area.getProvinceId()) {
            areaList.add(area.getProvinceId());
        }
        if (null != area.getCityId()) {
            areaList.add(area.getCityId());
        }
        if (null != area.getDistrictId()) {
            areaList.add(area.getDistrictId());
        }
        if (0 < areaList.size()) {
            List<Region> regions = regionCentService.findByIds(areaList);
            if (0 < regions.size()) {
                Map<Integer, String> reMap = regions.stream().collect(Collectors.toMap(Region::getId, Region::getName));
                StringBuilder sbd = new StringBuilder();
                if(StringUtils.isNotEmpty(reMap.get(areaDTO.getProvinceId()))){
//                        sbd.append(reMap.get(areaDTO.getProvinceId()));
                    areaDTO.setProvinceName(reMap.get(areaDTO.getProvinceId()));
                }
                if(StringUtils.isNotEmpty(reMap.get(areaDTO.getCityId()))){
//                        sbd.append(reMap.get(areaDTO.getCityId()));
                    areaDTO.setCityName(reMap.get(areaDTO.getCityId()));
                }
                if(StringUtils.isNotEmpty(reMap.get(areaDTO.getDistrictId()))){
//                        sbd.append(reMap.get(areaDTO.getDistrictId()));
                    areaDTO.setDistrictName(reMap.get(areaDTO.getDistrictId()));
                }
//                    areaDTO.setAddress(sbd.toString());
            }
        }
        dealJson (areaDTO,typeId);
        return areaDTO;
    }

    /**
     * 兼容历史数据
     */
    private void dealJson (Area param,Integer typeId){
        if(typeId == null){
            return;
        }
        QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
        organizationTypeQueryWrapper.eq("id", typeId);
        OrganizationType organizationType = organizationTypeService.getOne(organizationTypeQueryWrapper);
        String source = organizationType.getSource();
        if(org.apache.commons.lang3.StringUtils.isEmpty(source)){
            return;
        }
        Map<String,Object> map = new HashMap<>();
        JSONObject sourceJson = JSON.parseObject(source);
        JSONArray fields = sourceJson.getJSONArray("fields");
        if(CollectionUtil.isNotEmpty(fields)) {
            for (int i = 0; i < fields.size(); i++) {
                JSONObject fieldJsonObject = fields.getJSONObject(i);
                fieldJsonObject.remove("__config__");
                String vModel = fieldJsonObject.getString("vModel");
                //兼容以前数据
                if ("name".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getName() != null ? param.getName() : "");
                    map.put("name",param.getName() != null ? param.getName() : "");
                } else if ("code".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getCode() != null ? param.getCode() : "");
                    map.put("code",param.getCode() != null ? param.getCode() : "");
                } else  if ("buildingArea".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getBuildingArea() != null ? param.getBuildingArea() : "");
                    map.put("buildingArea",param.getBuildingArea() != null ? param.getBuildingArea() : "");
                } else if ("occupiedArea".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getOccupiedArea() != null ? param.getOccupiedArea() : "");
                    map.put("occupiedArea",param.getOccupiedArea() != null ? param.getOccupiedArea() : "");
                } else if ("longitude".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getLongitude() != null ? param.getLongitude() : "");
                    map.put("longitude",param.getLongitude() != null ? param.getLongitude() : "");
                } else if ("latitude".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getLatitude() != null ? param.getLatitude() : "");
                    map.put("latitude",param.getLatitude() != null ? param.getLatitude() : "");
                } else if ("address".equals(vModel)) {
                    fields.getJSONObject(i).put("defaultValue",param.getAddress() != null ? param.getAddress() : "");
                    map.put("address",param.getAddress() != null ? param.getAddress() : "");
                }else if ("sortField".equals(vModel)){
                    fields.getJSONObject(i).put("defaultValue",param.getSortField() != null ? param.getSortField() : "");
                    map.put("sortField",param.getSortField() != null ? param.getSortField() : "");
                } else {
                    if(param.getExpand() != null) {
                        JSONObject jsonObject = JSON.parseObject(param.getExpand());
                        if(jsonObject.get(vModel) != null) {
                            fields.getJSONObject(i).put("defaultValue", jsonObject.get(vModel));
                            map.put(vModel,jsonObject.get(vModel));
                        }else{
                            map.put(vModel,"");
                        }
                    }else{
                        map.put(vModel,"");
                    }
                }
            }
        }
        param.setExpand(JSON.toJSONString(sourceJson));
        param.setFullData(JSON.toJSONString(map));
    }

    private List<SpaceFunctionType> listFunctionType() {
        return spaceFunctionTypeService.list(new QueryWrapper<SpaceFunctionType>()
                .eq("org_type", OrganizationTypeEnum.AREA.getId()));
    }
}
